#ifndef _LOG_H_

#define _LOG_H_

#include <iostream>
#include <fstream>
#include <sstream>
#include "SystemTime.h"

using namespace std;

class CLog
{
private:
  ofstream f;
  CRITICAL_SECTION cs;
public:
  bool write0D;
  CLog(const std::string& filename, bool awrite0D = true) : f(filename.c_str(), ios::app | ios::binary), write0D(awrite0D)
  {
    InitializeCriticalSection(&cs);
  }
  ~CLog()
  {
    f.close();
    DeleteCriticalSection(&cs);
  }
  template<typename T> void write(const T& arg)
  {
    EnterCriticalSection(&cs);

    f<<arg;
    f.flush();
#ifdef CONSOLE
    cout << arg;
#endif
    LeaveCriticalSection(&cs);
  }
}; 

template<typename T> CLog& operator<< (CLog& log, const T& arg)
{
  log.write(arg);
  return log;
};

CLog& operator<< (CLog& log, const string& arg);
CLog& operator<< (CLog& log, char*& arg);

/*#define _log(a) \
{\
  ostringstream _tmp_stream_;\
  _tmp_stream_ << a; \
  (*pLog) << _tmp_stream_.str();\
}*/
#define _log(a)


#define _log2(a) \
{\
  ostringstream _tmp_stream_;\
  _tmp_stream_ << a; \
  (*pLog2) << _tmp_stream_.str();\
}


string strtime();

#ifdef debug
#define _D(a) _log(a)
#else
#define _D(a)
#endif

// === misc functions ===

string MakeUpper(string s);
bool getval(const string s, int& val);
bool getval(const string s, int& val, int defval);
string inttostr(const int x);
int WritePascalString(BYTE* to, string s);
int ReadPascalString(BYTE* from, string& s);

// === time functions ===
double DiffTime(const FILETIME ft2, const FILETIME ft1);
FILETIME AddTime(const FILETIME ft1, const double delta);
FILETIME GetNowTime();
string GetTimeStr(const FILETIME ft);
#endif
